﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WaterRegimenMonitor.Web.Domain;
using WaterRegimenMonitor.Common;

namespace WaterRegimenMonitor.Web.Code
{
    /// <summary>
    /// 权限检查特性。
    /// </summary>
    /// <remarks></remarks>
    /// <history>
    /// [zanezeng]               2012/03/09 11:04    创建
    /// </history>
    public class PermissionCheckAttribute : ActionFilterAttribute
    {
        #region Constructor

        /// <summary>
        /// 初始化类型<see cref="PermissionCheckAttribute"/>的新实例。
        /// </summary>
        /// <param name="allowedRoles">允许的角色列表。</param>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2012/03/09 11:09    创建
        /// </history>
        public PermissionCheckAttribute(string allowedRoles)
        {
            //判定是否指定了角色
            if (string.IsNullOrEmpty(allowedRoles))
            {
                //设置为空字符串数组
                this.m_Roles = new string[0];
            }
            else
            {
                //获得角色列表
                this.m_Roles = allowedRoles.Split(',', ';', '|');
            }
        }

        #endregion

        #region ---Public Method

        /// <summary>
        /// 当Action准备执行时促发。
        /// </summary>
        /// <param name="filterContext">上下文。</param>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2012/03/09 11:04    创建
        /// </history>
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            //判定是否已经登录
            if (filterContext.HttpContext.Request.IsAuthenticated)
            {
                //获得当前主体
                var principal = Helper.CurrentPrincipal;

                //判定是否为系统管理员
                if (principal.IsInRole("SystemAdmin"))
                {
                    //如果是系统管理员，则直接允许
                    return;
                }

                //判定是否为自由访问
                if (this.m_Roles.Contains("*"))
                {
                    //如果允许自由访问，则直接允许
                    return;
                }

                //判定是否包含指定角色
                foreach (string role in this.m_Roles)
                {
                    //判定是否包含角色
                    if (principal.IsInRole(role))
                    {
                        //如果包含了角色，则直接允许
                        return;
                    }
                }

                //抛出尚未授权异常
                throw new UnauthorizedException("您尚未授权访问此信息，请联系系统管理员获得此信息访问授权。");
            }
            else
            {
                //抛出尚未认证异常
                throw new UnauthenticatedException("您尚未登录，无法浏览此信息，请登录系统之后再试。");
            }
        }

        #endregion

        #region ---Field

        /// <summary>
        /// 允许的角色列表。
        /// </summary>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2012/03/09 11:10    创建
        /// </history>
        private string[] m_Roles;

        #endregion
    }
}